package com.xvxingan.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

/**
 * HTTP相关的操作
 * 
 * @Date 2011-10-9
 */
public class HttpUtil {
	public static final String CHARACTER_ENCODING = "UTF-8";
	public static final String PATH_SIGN = "/";
	public static final String METHOD_POST = "POST";

	/**
	 * 获取当前操作系统的类型
	 * 
	 * @return
	 */
	public static String getOsName() {
		String os = "";
		os = System.getProperty("os.name");
		return os;
	}

	/**
	 * 获取网卡地址mac
	 * 
	 * @param ia
	 * @return
	 * @throws SocketException
	 */
	private static String getMACAddress(InetAddress ia) throws SocketException {
		// 获得网络接口对象（即网卡），并得到mac地址，mac地址存在于一个byte数组中。
		byte[] mac = NetworkInterface.getByInetAddress(ia).getHardwareAddress();
		// 下面代码是把mac地址拼装成String
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < mac.length; i++) {
			if (i != 0) {
				sb.append("-");
			}
			// mac[i] & 0xFF 是为了把byte转化为正整数
			String s = Integer.toHexString(mac[i] & 0xFF);
			sb.append(s.length() == 1 ? 0 + s : s);
		}
		// 把字符串所有小写字母改为大写成为正规的mac地址并返回
		return sb.toString().toUpperCase();
	}

	/**
	 * 获取本地
	 * 
	 * @return
	 * @throws SocketException
	 */
	public static String getMACAddress() throws SocketException {
		InetAddress addr = getAddress();
		return getMACAddress(addr);
	}

	/**
	 * 获取Request来源的网卡地址
	 * 
	 * @param request
	 * @return
	 */
	public static String getIpAddr(HttpServletRequest request) {
		String ip = request.getHeader("X-Forwarded-For");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_CLIENT_IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}

	/**
	 * 获取指定IP的网卡地址
	 * 
	 * @param ipAddress
	 * @return
	 * @throws IOException
	 */
	public static String getMACAddress(String ipAddress) throws IOException {
		String str = "", strMAC = "", macAddress = "";
		Process pp = Runtime.getRuntime().exec("nbtstat -a " + ipAddress);
		InputStreamReader ir = new InputStreamReader(pp.getInputStream());
		LineNumberReader input = new LineNumberReader(ir);
		for (int i = 1; i < 100; i++) {
			str = input.readLine();
			if (str != null) {
				if (str.indexOf("MAC Address") > 1) {
					strMAC = str.substring(str.indexOf("MAC Address") + 14,
							str.length());
					break;
				}
			}
		}
		//
		if (strMAC.length() < 17) {
			return "Error!";
		}
		macAddress = strMAC.substring(0, 2) + ":" + strMAC.substring(3, 5)
				+ ":" + strMAC.substring(6, 8) + ":" + strMAC.substring(9, 11)
				+ ":" + strMAC.substring(12, 14) + ":"
				+ strMAC.substring(15, 17);
		//
		return macAddress;
	}

	/**
	 * 获取本机IP地址
	 * 
	 * @return
	 * @throws SocketException
	 */
	private static InetAddress getAddress() throws SocketException {
		for (Enumeration<NetworkInterface> interfaces = NetworkInterface
				.getNetworkInterfaces(); interfaces.hasMoreElements();) {
			NetworkInterface networkInterface = interfaces.nextElement();
			if (networkInterface.isLoopback() || networkInterface.isVirtual()
					|| !networkInterface.isUp()) {
				continue;
			}
			Enumeration<InetAddress> addresses = networkInterface
					.getInetAddresses();
			if (addresses.hasMoreElements()) {
				return addresses.nextElement();
			}
		}
		return null;
	}

	private static String inputStreamToString(InputStream is, String encode)
			throws Exception {
		StringBuffer buffer = new StringBuffer();
		BufferedReader rd = new BufferedReader(
				new InputStreamReader(is, encode));
		int ch;
		for (; (ch = rd.read()) > -1;) {
			buffer.append((char) ch);
		}
		rd.close();
		return buffer.toString();
	}

	/**
	 * get请求
	 * 
	 * @param url
	 * @return
	 * @throws ParseException
	 * @throws IOException
	 */
	public static String requestGet(String url) throws ParseException,
			IOException {
		DefaultHttpClient client = new DefaultHttpClient();
		HttpGet httpGet = new HttpGet(url);
		HttpResponse httpResponse = client.execute(httpGet);
		HttpEntity entity = httpResponse.getEntity();
		String result = "";
		if (entity != null)
			result = EntityUtils.toString(entity, "UTF-8");
		return result;
	}

	/**
	 * 发送带文件上传以及文本域的post请求
	 * 
	 * @param urlString
	 *            post请求地址
	 * @param params
	 *            文本
	 * @param files
	 *            文件
	 * @return 返回的html
	 * @throws Exception
	 */
	public static String sendPostFileRequest(String urlString,
			Map<String, String> params, Map<String, String> files, String encode)
			throws Exception {
		// 是否在控制台打印请求参数，方便调用
		boolean printArgs = false;
		// 构送请求http请求参数
		String BOUNDARY = "---------------------------7d4a6d158c9"; // 分隔线
		List<byte[]> headerList = new ArrayList<byte[]>();
		List<byte[]> contentList = new ArrayList<byte[]>();
		byte[] end = ("--" + BOUNDARY + "--\r\n").getBytes();
		int contentLength = 0;
		if (params != null && params.size() > 0) {
			for (String key : params.keySet()) {
				byte[] header = ("--" + BOUNDARY
						+ "\r\nContent-Disposition: form-data;name=\"" + key + "\"\r\n\r\n")
						.getBytes(encode);
				byte[] content = params.get(key).getBytes(encode);
				headerList.add(header);
				contentList.add(content);
				contentLength += header.length + content.length
						+ "\r\n".getBytes().length;
				if (printArgs) {
					System.out.print(new String(header, encode));
					System.out.print(new String(content, encode));
					System.out.print(new String("\r\n".getBytes()));
				}
			}
		}
		if (files != null && files.size() > 0) {
			for (String key : files.keySet()) {
				String filename = files.get(key).substring(
						files.get(key).lastIndexOf("/") + 1);
				byte[] header = ("--" + BOUNDARY
						+ "\r\nContent-Disposition: form-data; name=\"" + key
						+ "\"; filename=\"" + filename + "\"\r\nContent-Type: multipart/form-data\r\n\r\n")
						.getBytes(encode);
				byte[] content = FileUtils
						.readFileToByteArray(new File(files.get(key)));
				headerList.add(header);
				contentList.add(content);
				contentLength += header.length + content.length
						+ "\r\n".getBytes().length;
				if (printArgs) {
					System.out.print(new String(header, encode));
					System.out.print(new String(content));
					System.out.print(new String("\r\n".getBytes()));
				}
			}
		}
		contentLength += end.length;
		if (printArgs) {
			System.out.print(new String(end));
		}
		// 发送http请求
		URL url = new URL(urlString);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setRequestMethod(METHOD_POST);
		conn.setConnectTimeout(5000);// 连接超时 单位毫秒
		conn.setReadTimeout(5000);// 读取超时 单位毫秒
		conn.setDoOutput(true);
		conn.setRequestProperty("Content-Type",
				"multipart/form-data; boundary=" + BOUNDARY);
		conn.setRequestProperty("Content-Length", String.valueOf(contentLength));
		OutputStream os = conn.getOutputStream();
		for (int i = 0; i < headerList.size(); i++) {
			os.write(headerList.get(i));
			os.write(contentList.get(i));
			os.write("\r\n".getBytes());
		}
		os.write(end);
		os.flush();
		os.close();
		// 获取http请求结果
		InputStream is = conn.getInputStream();
		String str = inputStreamToString(is, encode);
		is.close();
		conn.disconnect();
		return str;
	}
}